package com.kamistoat.meimeichat.meimeichatserverapplication.netty.handlers;

import com.alibaba.fastjson.JSON;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.NettyServerBizHandler;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.service.NettyUserService;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettyConstants;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettySocketChannelUtil;
import com.kamistoat.meimeichatserveraggrement.protocol.msg.MsgRequest;
import com.kamistoat.meimeichatserveraggrement.protocol.msg.MsgResponse;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 私聊Handler。向对应用户转发消息
 * TODO 改进点。之后私聊可以改成点对点UDP打洞通信，直接绕过服务器转发
 */
@Component
@ChannelHandler.Sharable
public class MsgHandlerServer extends NettyServerBizHandler<MsgRequest> {
    @Autowired
    NettyUserService nettyUserService;

    /**
     * @param channel
     * @param msgRequest
     * @Warning:子类只需要重写该方法
     */
    @Override
    public void channelRead(Channel channel, MsgRequest msgRequest) {
        if(msgRequest == null) return;
        logger.info("经服务器转发的消息: " + JSON.toJSONString(msgRequest));
//        // 这里用了异步去完成聊天消息入库。
//        CompletableFuture<Void> asyncAppendChatRecord = nettyUserService.asyncAppendChatRecord(
//                msgRequest.getSenderId(),
//                msgRequest.getReceiverId(),
//                msgRequest.getMsgText(),
//                msgRequest.getMsgDate(),
//                msgRequest.getMsgType(),
//                NettyConstants.TalkType.Friend.getCode()
//        );
//        // 异步添加好友-自己的对话框. 因为能保证自己-好友的对话框一定存在，好友-自己的可能已经被好友删除或者压根不存在
//        // 尤其是陌生人私聊的情况，更需要提前拉起对话框
//        CompletableFuture<Void> asyncAppendTalkBox = nettyUserService.asyncAppendTalkBox(
//                msgRequest.getReceiverId(),
//                msgRequest.getSenderId(),
//                NettyConstants.TalkType.Friend.getCode()
//        );

        // 获取对方的channel
        Channel friendChannel = NettySocketChannelUtil.getChannel(msgRequest.getReceiverId());
        // 若对方channel不存在说明对方离线，那就直接不做转发就是了。
        // 而且由于消息已经入库，所以当对方下次上线时能够收到存放在数据库中的消息
        if(friendChannel != null){
            MsgResponse msgResponse = new MsgResponse();
            BeanUtils.copyProperties(msgRequest, msgResponse);
//            try {
//                // 必须要等，否则在线用户可能都收不到
//                CompletableFuture.allOf(asyncAppendChatRecord, asyncAppendTalkBox).get();
//            } catch (InterruptedException | ExecutionException e) {
//                e.printStackTrace();
//            }
            friendChannel.writeAndFlush(msgResponse);
        }
    }
}
